#include "fileoperations.h"
#include <QDebug>
#include <QProcess>
#include <QTextStream>
#include <QtConcurrent/QtConcurrent>
#include <QFutureWatcher>
FileOperations::FileOperations(QObject *parent) : QObject(parent)
{
}

bool FileOperations::copyFileMulti(const QVariantList &sourcePaths, const QString &destinationPaths, bool outPut) {
    qInfo() << "source" << sourcePaths.size() << "destination" << destinationPaths.size();

    int totalFiles = sourcePaths.size();
    QAtomicInt filesCompleted = 0; // 使用线程安全的 QAtomicInt
    cancelRequested = false;

    QtConcurrent::run([this, sourcePaths, destinationPaths, totalFiles, &filesCompleted, outPut]() {
        //计算总大小
        qint64 totalBytes = 0;
        for (int i = 0; i < sourcePaths.size(); ++i){
            QString sourcePath = sourcePaths[i].toString();
            QFile sourceFile(sourcePath);
            totalBytes += sourceFile.size();
        }
        qWarning() << "totalBytes" << totalBytes;
        //定义已复制的大小
        qint64 bytesCopied = 0;
        const qint64 bufferSize = 64 * 1024; // 64 KB buffer
        QByteArray buffer;

        for (int i = 0; i < sourcePaths.size(); ++i) {
            if (cancelRequested) {
                qWarning() << "All transfers canceled.";
                qWarning() << "filesCompleted.loadRelaxed()" << filesCompleted.loadRelaxed();
                //emit allFilesSuccessfullyExported(filesCompleted.loadRelaxed(), totalFiles);
                return;
            }

            QString sourcePath = sourcePaths[i].toString();
            QFile copyFile(sourcePath);
            // 提取源文件的文件名
            QFileInfo sourceFileInfo(sourcePath);
            QString fileExtension = sourceFileInfo.suffix().toLower();
            QString folderName;
            QString targetFolder;
            if(outPut){
                // 根据文件扩展名选择文件夹
                if (fileExtension == "log") {
                    folderName = "日志";
                } else if (fileExtension == "jpg" || fileExtension == "png") {
                    folderName = "图片";
                } else if (fileExtension == "rknn") {
                    folderName = "模型";
                } else if (fileExtension == "yaml") {
                    folderName = "配置";
                }
                targetFolder = destinationPaths + folderName;
                // 创建目标文件夹路径
                QDir dir(targetFolder);
                if (!dir.exists()) {
                    if (!dir.mkpath(targetFolder)) {
                        qWarning() << "Failed to create folder:" << targetFolder;
                        emit fileFailExported();
                        return;
                    }
                }
            }else{
                targetFolder = destinationPaths;
            }

            // 最终的目标文件路径
            QString destinationFilePath = targetFolder + "/" + sourceFileInfo.fileName();
            QFile destinationFile(destinationFilePath);

            if (!copyFile.open(QIODevice::ReadOnly)) {
                qWarning() << "Failed to open source file:" << sourcePath;
                emit fileFailExported();
                return ;
            }

            if (!destinationFile.open(QIODevice::WriteOnly)) {
                qWarning() << "Failed to open destination file:" << destinationFilePath;
                emit fileFailExported();
                return ;
            }


            while (!copyFile.atEnd()) {
                if (cancelRequested) {
                    qWarning() << "Copy operation canceled.";
                    copyFile.close();
                    destinationFile.close();
                    destinationFile.remove(); // 删除未完成的目标文件
                    emit fileFailExported();
                    return ;
                }

                buffer = copyFile.read(bufferSize);
                if (buffer.isEmpty()) {
                    qDebug() << "Error reading file.";
                    emit fileFailExported();
                    return ;
                }

                qint64 bytesWritten = destinationFile.write(buffer);
                if (bytesWritten == -1) {
                    qDebug() << "Error writing to file.";
                    emit fileFailExported();
                    return ;
                }

                bytesCopied += bytesWritten;
                //qDebug() << "bytesCopied" << bytesCopied << "totalBytes" << totalBytes;

                emit copyProgressUpdated(bytesCopied, totalBytes);

            }
            copyFile.close();

            filesCompleted.fetchAndAddRelaxed(1); // 增加完成的文件计数
        }
        if(bytesCopied == totalBytes){
            emit fileSuccessfullyExported();
        }
        qDebug() << "filesCompleted.loadRelaxed()" << filesCompleted.loadRelaxed();
        //emit allFilesSuccessfullyExported(filesCompleted.loadRelaxed(), totalFiles);
    });

    return true;
}




bool FileOperations::copyFileV2(const QString &sourcePath, const QString &destinationPath, bool output) {
    qDebug() << "url:Copying file from" << sourcePath << "to" << destinationPath;
    cancelRequested = false;

    // 提取源文件的文件名
    QFileInfo sourceFileInfo(sourcePath);
    QString fileExtension = sourceFileInfo.suffix().toLower();
    QString folderName;
    QString targetFolder;
    if(output){
        // 根据文件扩展名选择文件夹
        if (fileExtension == "log") {
            folderName = "日志";
        } else if (fileExtension == "jpg" || fileExtension == "png") {
            folderName = "图片";
        } else if (fileExtension == "rknn") {
            folderName = "模型";
        } else if (fileExtension == "yaml") {
            folderName = "配置";
        }
        targetFolder = destinationPath + folderName;
        // 创建目标文件夹路径
        QDir dir(targetFolder);
        if (!dir.exists()) {
            if (!dir.mkpath(targetFolder)) {
                qWarning() << "Failed to create folder:" << targetFolder;
                emit fileFailExported();
                return false;
            }
        }
    }else{
        targetFolder = destinationPath;
    }

    // 最终的目标文件路径
    QString destinationFilePath = targetFolder + "/" + sourceFileInfo.fileName();

    QtConcurrent::run([this, sourcePath, destinationFilePath]() {
        copyFileIner(sourcePath, destinationFilePath);
    });

    return true;
}

void FileOperations::cancelCopy() {
    cancelRequested = true; // 设置取消标志为 true
}

bool FileOperations::copyFile(const QString &sourcePath, const QString &destinationPath)
{
    // qDebug() << "url:Copying file from" << sourcePath << "to" << destinationPath;

    // QFileInfo sourceInfo(sourcePath);
    // if (sourceInfo.isDir()) {
    //     qDebug() << "Source is a directory. Calling copyDir.";
    //     return copyDir(sourcePath, destinationPath);
    // } else {
    //     qDebug() << "Copying file from" << sourcePath << "to" << destinationPath;

    //     // 使用 QProcess 调用系统的 cp 命令
    //     QProcess process;
    //     QStringList arguments;
    //     arguments << sourcePath << destinationPath;
    //     process.start("cp", arguments);
    //     process.waitForFinished();

    //     int exitCode = process.exitCode();
    //     if (exitCode != 0) {
    //         qDebug() << "Failed to copy file. Error:" << process.readAllStandardError();
    //         emit fileFailExported();
    //         return false;
    //     }
    //     emit fileSuccessfullyExported();
    //     return true;
    // }
}

bool FileOperations::copyDir(const QString &sourceDirPath, const QString &destinationDirPath)
{
    // QDir sourceDir(sourceDirPath);
    // QDir destinationDir(destinationDirPath);

    // if (!destinationDir.exists()) {
    //     qDebug() << "Destination directory does not exist. Creating path.";
    //     if (!destinationDir.mkpath(".")) {
    //         qDebug() << "Failed to create destination directory.";
    //         emit fileFailExported();
    //         return false;
    //     }
    // }

    // foreach (QString entry, sourceDir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::AllDirs, QDir::DirsFirst)) {
    //     QString sourcePath = sourceDir.filePath(entry);
    //     QString destinationPath = destinationDir.filePath(entry);

    //     QFileInfo sourceInfo(sourcePath);
    //     if (sourceInfo.isDir()) {
    //         qDebug() << "Entry is a directory. Recursively copying directory:" << sourcePath;
    //         if (!copyDir(sourcePath, destinationPath)) {
    //             qDebug() << "Failed to copy directory:" << sourcePath;
    //             emit fileFailExported();
    //             return false;
    //         }
    //     } else {
    //         qDebug() << "Copying file from" << sourcePath << "to" << destinationPath;

    //         // 使用 QProcess 调用系统的 cp 命令
    //         QProcess process;
    //         QStringList arguments;
    //         arguments << sourcePath << destinationPath;
    //         process.start("cp", arguments);
    //         process.waitForFinished();

    //         int exitCode = process.exitCode();
    //         if (exitCode != 0) {
    //             qDebug() << "Failed to copy file:" << sourcePath << "Error:" << process.readAllStandardError();
    //             emit fileFailExported();
    //             return false;
    //         }
    //     }
    // }
    // emit fileSuccessfullyExported();

    // return true;
}

QVariantList FileOperations::readFile(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return QVariantList(); // 返回空列表
    }

    const qint64 chunkSize = 1024;  // 每次读取的字节大小
    const int targetLines = 50;    // 目标行数
    QStringList lines;            // 用于存储完整行
    qint64 filePos = file.size();  // 从文件尾部开始

    QString leftover;  // 保存块之间未完整的行
    while (filePos > 0 && lines.size() < targetLines) {
        // 计算新的起始位置
        filePos = qMax(static_cast<qint64>(0), filePos - chunkSize);
        file.seek(filePos);

        // 读取块并转为字符串
        QByteArray data = file.read(chunkSize);
        QString chunk = QString::fromUtf8(data);

        // 如果有剩余未完整的行，拼接到当前块的末尾
        chunk.append(leftover);

        // 按行分割
        QStringList chunkLines = chunk.split('\n', Qt::SkipEmptyParts);

        // 保存当前块中未完成的行（第一行可能是残缺的）
        leftover = chunkLines.takeFirst();

        // 将当前块的完整行加入列表
        lines = chunkLines + lines;

    }

    file.close();

    // 如果还有残缺的行（最后一次读取后的剩余），也加入结果
    if (!leftover.isEmpty()) {
        lines.prepend(leftover);
    }

    // 保留最后50行
    if (lines.size() > targetLines) {
        lines = lines.mid(lines.size() - targetLines, targetLines);
    }

    // 转换为 QVariantList，并倒序
    QVariantList result;
    for (int i = lines.size() - 1; i >= 0; --i) {
        result.append(lines.at(i));
    }
    qDebug() << "result" <<result;
    return result;
}

bool FileOperations::copyFileIner(const QString &sourcePath, const QString &destinationPath) {
    QFileInfo sourceInfo(sourcePath);
    if (sourceInfo.isDir()) {
        qInfo() << "Source is a directory. CopyDir functionality needs to be implemented.";
        // Implement copyDir if needed
        emit fileFailExported();
        return false;
    }

    QFile sourceFile(sourcePath);
    QFile destinationFile(destinationPath);

    if (!sourceFile.open(QIODevice::ReadOnly)) {
        qWarning() << "Failed to open source file:" << sourcePath <<
            "-" << destinationFile.errorString();
        emit fileFailExported();
        return false;
    }

    if (!destinationFile.open(QIODevice::WriteOnly)) {
        qWarning() << "Failed to open destination file:" << destinationPath <<
            "-" << destinationFile.errorString();;
        emit fileFailExported();
        return false;
    }

    qint64 totalBytes = sourceFile.size();
    qint64 bytesCopied = 0;
    const qint64 bufferSize = 64 * 1024; // 64 KB buffer
    QByteArray buffer;

    while (!sourceFile.atEnd()) {
        if (cancelRequested) {
            qWarning() << "Copy operation canceled.";
            sourceFile.close();
            destinationFile.close();
            destinationFile.remove(); // 删除未完成的目标文件
            emit fileFailExported();
            return false;
        }

        buffer = sourceFile.read(bufferSize);
        if (buffer.isEmpty()) {
            qWarning() << "Error reading file.";
            emit fileFailExported();
            return false;
        }

        qint64 bytesWritten = destinationFile.write(buffer);
        if (bytesWritten == -1) {
            qWarning() << "Error writing to file.";
            emit fileFailExported();
            return false;
        }

        bytesCopied += bytesWritten;
        //qDebug() << "bytesCopied" << bytesCopied << "totalBytes" << totalBytes;

        emit copyProgressUpdated(bytesCopied, totalBytes);


    }

    sourceFile.close();
    destinationFile.close();

    if (bytesCopied == totalBytes) {
        emit fileSuccessfullyExported();
        return true;
    } else {
        qInfo() << "File copy incomplete.";
        emit fileFailExported();
        return false;
    }
}

